﻿//////////////////////////////////////////////////////////////////////////////
//
//  Copyright © 1998-2024 Glodon Company Limited.  All rights reserved.
//
//  Use of this software is subject to the terms of the Glodon license
//  agreement provided at the time of installation or download, or which
//  otherwise accompanies this software in either electronic or hard copy form.  
//
//////////////////////////////////////////////////////////////////////////////


#pragma once
#include "IDbObject.h"
#include "GcmpModelInterface.h"
#include "OwnerPtr.h"

namespace gcmp
{
    class IElement;
    class IOpeningRelationshipBehavior;
    class IOpeningGraphicsElementShapeComponent;
    class IOpenedGraphicsElementShapeComponent;
    class IJoinRelationshipBehavior;
    class IJoinedGraphicsElementShapeComponent;
    class ICutRelationshipBehavior;
    class ICutterGraphicsElementShapeComponent;
    class ICutteeGraphicsElementShapeComponent;
    class IGeometryRelationship;
    class IGraphicsElementShape;
    class ClassId;

    /// \brief 几何关系组件(如连接、打洞、扣减等)
    class GCMP_MODEL_INTERFACE_EXPORT IGeometryRelationshipComponent : public IDbObject
    {
        DEFINE_CAST_DERIVED(gcmp::IGeometryRelationshipComponent, gcmp::IDbObject);

    public:
        /// \brief 创建平台默认的几何关系组件。
        ///
        /// 此行为创建一个平台默认的几何关系组件。
        /// \return OwnerPtr<IGeometryRelationshipComponent> 平台默认的几何关系组件。
        static OwnerPtr<IGeometryRelationshipComponent> Create();
#pragma region 打洞
        /// \brief 获取打洞关系实例
        /// \return IOpeningRelationshipBehavior* 当前Element的打洞关系实例
        virtual IOpeningRelationshipBehavior* GetOpeningRelationship() = 0;

        /// \brief 获取打洞关系实例(只读)
        /// \return const IOpeningRelationshipBehavior* 当前Element的打洞关系实例
        virtual const IOpeningRelationshipBehavior* GetOpeningRelationship() const = 0;

        /// \brief 设置开洞行为接口
        /// \param opOpenRelationshipBehavior 开洞行为指针
        virtual void SetOpeningRelationship(OwnerPtr<IOpeningRelationshipBehavior> opOpenRelationshipBehavior) = 0;

        /// \return 被打洞图形显示组件接口
        virtual IOpenedGraphicsElementShapeComponent* GetOpenedGraphicsElementShapeComponent() = 0;

        /// \brief 获得被打洞图形显示组件接口
        /// \return 被打洞图形显示组件接口
        virtual const IOpenedGraphicsElementShapeComponent* GetOpenedGraphicsElementShapeComponent() const = 0;

        /// \brief 获得打洞图形显示组件接口
        /// \return 打洞图形显示组件接口
        virtual IOpeningGraphicsElementShapeComponent* GetOpeningGraphicsElementShapeComponent() = 0;

        /// \brief 获得打洞图形显示组件接口(只读)
        /// \return 打洞图形显示组件接口
        virtual const IOpeningGraphicsElementShapeComponent* GetOpeningGraphicsElementShapeComponent() const = 0;

        /// \brief 设置打洞图形显示组件
        /// \param opOpeningGraphicsElementShape 待设置打洞图示显示组件
        virtual void SetOpeningGraphicsElementShapeComponent(OwnerPtr<IOpeningGraphicsElementShapeComponent> opOpeningGraphicsElementShape) = 0;

        /// \brief 设置被打洞图形显示组件
        /// \param opOpenedGraphicsElementShape 待设置被打洞图示显示组件
        virtual void SetOpenedGraphicsElementShapeComponent(OwnerPtr<IOpenedGraphicsElementShapeComponent> opOpenedGraphicsElementShape) = 0;
#pragma endregion

#pragma region 扣减
        /// \brief 获取扣减关系实例
        /// \return ICutRelationshipBehavior* 当前Element的扣减关系实例
        virtual ICutRelationshipBehavior* GetCutRelationship() = 0;

        /// \brief 获取扣减关系实例(只读)
        /// \return const ICutRelationshipBehavior* 当前Element的扣减关系实例
        virtual const ICutRelationshipBehavior* GetCutRelationship() const = 0;

        /// \brief 设置扣减关系行为接口
        /// \param opCutRelationshipBehavior 扣减关系行为接口
        virtual void SetCutRelationship(OwnerPtr<ICutRelationshipBehavior> opCutRelationshipBehavior) = 0;

        /// \brief 获得扣减图形显示组件接口
        /// \return 扣减图形显示组件接口
        virtual const ICutterGraphicsElementShapeComponent* GetCutterGraphicsElementShapeComponent() const = 0;

        /// \brief 获得扣减图形显示组件接口
        /// \return 扣减图形显示组件接口
        virtual ICutterGraphicsElementShapeComponent* GetCutterGraphicsElementShapeComponent() = 0;

        /// \brief 获得被扣减图形显示组件接口
        /// \return 被扣减图形显示组件接口
        virtual const ICutteeGraphicsElementShapeComponent* GetCutteeGraphicsElementShapeComponent() const = 0;

        /// \brief 获得被扣减图形显示组件接口
        /// \return 被扣减图形显示组件接口
        virtual ICutteeGraphicsElementShapeComponent* GetCutteeGraphicsElementShapeComponent() = 0;

        /// \brief 设置被扣减图形显示组件
        /// \return opCutteeGraphicsElementShape 待设置被扣减图形显示组件
        virtual void SetCutteeGraphicsElementShapeComponent(OwnerPtr<ICutteeGraphicsElementShapeComponent> opCutteeGraphicsElementShape) = 0;

        /// \brief 设置扣减图形显示组件
        /// \return opCutterGraphicsElementShape 待设置扣减图形显示组件
        virtual void SetCutterGraphicsElementShapeComponent(OwnerPtr<ICutterGraphicsElementShapeComponent> opCutterGraphicsElementShape) = 0;
#pragma endregion

#pragma region 连接

        /// \brief 获取连接关系实例
        /// \return IJoinRelationshipBehavior* 当前Element的连接关系实例
        virtual IJoinRelationshipBehavior* GetJoinRelationship() = 0;

        /// \brief 获取连接关系实例(只读)
        /// \return const IJoinRelationshipBehavior* 当前Element的连接关系实例
        virtual const IJoinRelationshipBehavior* GetJoinRelationship() const = 0;
#pragma endregion

#pragma region 自定义几何关系

        /// \brief 添加几何关系
        /// \param opGeometryRelationship 几何关系
        /// \return true,添加成功;false,添加失败(如重复添加)
        virtual bool AddGeometryRelationship(OwnerPtr<IGeometryRelationship> opGeometryRelationship) = 0;

        /// \brief 获取所有的自定义几何关系
        /// \return 所有的自定义几何关系
        virtual const std::vector<OwnerPtr<IGeometryRelationship>>& GetGeometryRelationships() const = 0;

        /// \brief 根据index获取对应的几何关系
        /// \param index 几何关系的index
        /// \return index对应的几何关系，若无对应几何关系则返回nullptr
        virtual IGeometryRelationship* GetGeometryRelationshipByIndex(int index) = 0;

        /// \brief 根据index获取对应的几何关系
        /// \param index 几何关系的index
        /// \return index对应的几何关系，若无对应几何关系则返回nullptr
        virtual const IGeometryRelationship* GetGeometryRelationshipByIndex(int index) const = 0;

        /// \brief 获取几何关系计算后的图形表达
        /// 
        /// Instance的ModelGRep计算时，会通过此接口获取所有几何关系计算后的图形表达，作为ModelGrep计算的起点
        /// \return 几何关系计算后的图形表达
        virtual const IGraphicsElementShape* GetResultGraphicsElementShape() const = 0;

        /// \brief 获取给定几何关系前面对象的IGraphicsElementShape，按照优先级关系，优先级高的在前
        /// \param pGeometryRelationship 几何关系对象
        /// \return IGraphicsElementShape 前面对象的IGraphicsElementShape结果
        virtual const IGraphicsElementShape* GetPreviousGraphicsElementShape(const IGeometryRelationship* pGeometryRelationship) const = 0;

        /// \brief 获取给定几何关系前面一个对象，按照优先级关系，优先级高的在前
        /// \param pGeometryRelationship 几何关系对象
        /// \return IGeometryRelationship 前面一个对象，如果没有返回nullptr
        virtual const IGeometryRelationship* GetPreviousGeometryRelationship(const IGeometryRelationship* pGeometryRelationship) const = 0;

#pragma endregion

    public:
        /// \brief 设置该行为所属Element
        /// \param pOwnerElement 所属Element
        /// \return bool
        virtual bool SetOwnerElement(IElement* pOwnerElement) = 0;

        /// \brief 获得该行为所属的Element
        /// \return 所属的Element
        virtual IElement* GetOwnerElement() = 0;

        /// \brief 获得该行为所属的Element
        /// \return 所属的Element
        virtual const IElement* GetOwnerElement() const = 0;
    };
}

